/* 
  网格法线平滑.cl
  

  Created by mbt on 2017/6/12.

*/


#define CurrentID ((get_group_id(1)*get_num_groups(0)*get_num_groups(2)) + (get_group_id(2)*get_num_groups(0)) + get_group_id(0))


//取相应轴向信息
/*uint f_getCorrespondingVoxel(__global ulong2* hash, uint eNum, uint3 coord, uchar mask) {
    switch(mask){
        case 1:
            ++coord.x;
            break;
        case 2:
            --coord.x;
            break;
        case 4:
            ++coord.y;
            break;
        case 8:
            --coord.y;
            break;
        case 16:
            ++coord.z;
            break;
        case 32:
            --coord.z;
            break;
    }
    
    ulong newHash = f_SamplingHash(hash, coord);
    return f_BinarySearch(hash, newHash, eNum);
    
}*/


__kernel void f_SmoothNormal(__global float4* vertex, __global float4* normal, __global ulong2* Hash, __global uint2* HashIndex, uint eNum) {
    size_t id = CurrentID;
    if(id<eNum){
        ulong tmpHash = Hash[id].s0;
        ++id;
        if(id<eNum && tmpHash != Hash[id].s0 && Hash[id].s0){
            float3 newNormal = normal[ HashIndex[id].s0 ].xyz;
            tmpHash = Hash[id].s0;
            float3 tmpNormal[6];
            tmpNormal[0] = newNormal;
            uchar i=1;
            for(; i<6; ++i){
                if( (id+i)<eNum && tmpHash == Hash[id+i].s0){
                    tmpNormal[i] = normal[ HashIndex[id+i].s0 ].xyz;
                    newNormal += tmpNormal[i];
                    
                }else break;
            }
            
            float len = 0.0;
            newNormal = normalize(newNormal);
            for(uchar ia=0; ia<i; ++ia){
                len += dot(newNormal, tmpNormal[ia]);
                //float d = dot(newNormal, newNormal);
            }
            len /= (3 + (i*6.0));
            //printf("len %f \n", len);
            for(uchar ia=0; ia<i; ++ia){
                if(id+ia<eNum) normal[ HashIndex[id+ia].s0 ] = (float4)(newNormal, len);
            }
            
        }
        
    } 
    
    /*if(id==1){
        for (uint i=0; i<100; ++i) {
            //printf("v4 = %v4f \n", vertex[i]);
			
			//printf("hash %#v2hx \n", HashIndex[i]);
			//printf(" %u \n", Hash[i].s0);
			//printf(" %#v2hx \n", Hash[i]);
			//printf("hash %u \n", rangeOffset[i].s0);				
			//printf(" %u \n", rangeNum[i]);
		}
    }*/
}


